package com.mlizhi.base;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Observable;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;

/**
 *
 * @author TroyLi 存app的会话数据
 *
 */
public class Session extends Observable {

	/** Log tag */
	private final static String TAG = "Session";

	/** Application Context */
	private Context mContext;

	/** The application debug mode */
	public boolean isDebug;

	/** The application uid */
	private String uid;

	/** The mobile device screen size */
	private String screenSize;

	/** The version of OS */
	private int osVersion;


	/** Indicate whether auto clear cache when user exit */
	private boolean isAutoClearCache;

	// /** The channel id */
	// private String cid;
	//
	// /** The SDK id */
	// private String cpid;
	//
	/** The Application Debug flag */
	private String debugType;

	/** The Application Version Code */
	private int versionCode;

	/** The Application package name */
	private String packageName;

	/** The Application version name */
	private String versionName;

	/** The Application version name */
	private String appName;

	/** The mobile IMEI code */
//	private String imei;

	/** The mobile sim code */
//	private String sim;

	/** The mobile mac address */
	private String macAddress;

	/**
	 * The mobile model such as "Nexus One" Attention: some model type may have
	 * illegal characters
	 */
	private String model;

	/** The user-visible version string. E.g., "1.0" */
	private String buildVersion;

	/** User login name */
	private String userName;

	/** User login icon */
	private String userIcon;

	/** User login account */
	private String account;

	/** User login password */
	private String password;

	/** Indicate whether new version is available */
	private boolean isUpdateAvailable;

	/** The new version name */
	private String updateVersionName;

	/** The new version code */
	private int updateVersionCode;

	/** The new version description */
	private String updateVersionDesc;

	/** The new version update uri */
	private String updateUri;

	/** The new version update level(Force Update/Option Update) */
	private int updateLevel;

	/** The new version APK download task id */
	private long updateId;

	/** The cloud service device bind flag */
	private boolean isDeviceBinded;

	/** The mobile device id */
	private String deviceId;

	/** FIXME The apps upgrade number */
	private int upgradeNumber;

	/** The apps update check time */
	private long updataCheckTime;

	/** The current version */
	private int lastVersion;

	/** 上次更新splash的时间戳 */
	private long splashTime;

	/** 上次更新splash的id */
	private long splashId;

	/** 用户地址 */
	private String userSex;

	private String userBriday;

	private String userSkinType;

	private String userAddress;

	/** Session Manager */
	private SessionManager mSessionManager;

	/** The singleton instance */
	private static Session mInstance;

	private TelephonyManager telMgr = null;

	/**
	 * default constructor
	 *
	 * @param context
	 */
	private Session(Context context) {

		synchronized (this) {
			mContext = context;
			osVersion = Build.VERSION.SDK_INT;// 版本号
			buildVersion = Build.VERSION.RELEASE;// 版本字符串
			try {
				model = URLEncoder.encode(Build.MODEL, "UTF-8"); // 版本

			} catch (UnsupportedEncodingException e) {
			}

			readSettings();
		}
	}

	/*
	 * 读取用户所有的设置
	 */
	private void readSettings() {
//		new Thread() {
//			public void run() {
		mSessionManager = SessionManager.get(mContext);
		addObserver(mSessionManager);
		HashMap<String, Object> preference = mSessionManager.readPreference();
		uid = (String) preference.get(SessionManager.P_USER_UID);
		userIcon = (String) preference.get(SessionManager.P_USER_USERICON);
		userName = (String) preference.get(SessionManager.P_USER_USERNAME);
		account = (String) preference.get(SessionManager.P_USER_ACCOUNT);
		password = (String) preference.get(SessionManager.P_USER_PASSWORD);
		screenSize = (String) preference.get(SessionManager.P_SCREEN_SIZE);
		isAutoClearCache = (Boolean) preference.get(SessionManager.P_CLEAR_CACHE);
		upgradeNumber = (Integer) preference.get(SessionManager.P_UPGRADE_NUM);
		updataCheckTime = (Long) preference.get(SessionManager.P_PRODUCT_UPDATE_CHECK_TIMESTAMP);
		updateId = (Long) preference.get(SessionManager.P_UPDATE_ID);
		lastVersion = (Integer) preference.get(SessionManager.P_CURRENT_VERSION);
		isUpdateAvailable = (Boolean) preference.get(SessionManager.P_UPDATE_AVAILABIE);
		updateVersionName = (String) preference.get(SessionManager.P_UPDATE_VERSION_NAME);
		updateVersionCode = (Integer) preference.get(SessionManager.P_UPDATE_VERSION_CODE);
		updateVersionDesc = (String) preference.get(SessionManager.P_UPDATE_DESC);
		updateUri = (String) preference.get(SessionManager.P_UPDATE_URI);
		updateLevel = (Integer) preference.get(SessionManager.P_UPDATE_LEVEL);
		splashId = (Long) preference.get(SessionManager.P_SPLASH_ID);
		splashTime = (Long) preference.get(SessionManager.P_SPLASH_TIME);
		userSex = (String) preference.get(SessionManager.P_USER_SEX);
		userBriday = (String) preference.get(SessionManager.P_USER_BRIDAY);
		userSkinType = (String) preference.get(SessionManager.P_USER_SKIN_TYPE);
		getApplicationInfo();
//			};
//		}.start();
	}

	public static Session get(Context context) {
		if (mInstance == null) {
			mInstance = new Session(context);
		}
		return mInstance;
	}

	public String getUid() {
		return uid;
	}

	public void setUid(String uid) {
		this.uid = uid;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_UID, uid));
	}

	public String getScreenSize() {
		return screenSize;
	}

	public void setScreenSize(Activity activity) {

		DisplayMetrics dm = new DisplayMetrics();
		activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
		this.screenSize = dm.widthPixels < dm.heightPixels ? dm.widthPixels + "#" + dm.heightPixels : dm.heightPixels + "#" + dm.widthPixels;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_SCREEN_SIZE, screenSize));
	}

	public int getOsVersion() {
		return osVersion;
	}

	private void getApplicationInfo() {

		final PackageManager pm = (PackageManager) mContext.getPackageManager();
		try {
			final PackageInfo pi = pm.getPackageInfo(mContext.getPackageName(), 0);
			versionName = pi.versionName;
			versionCode = pi.versionCode;

			final ApplicationInfo ai = pm.getApplicationInfo(mContext.getPackageName(), PackageManager.GET_META_DATA);
			// cid = ai.metaData.get("meilz_cid").toString();
			// cpid = ai.metaData.get("meilz_cpid").toString();
			debugType = ai.metaData.get("mlizhi_debug").toString();

			if ("1".equals(debugType)) {
				// developer mode
				isDebug = true;
			} else if ("0".equals(debugType)) {
				// release mode
				isDebug = false;
			}
			Utils.sDebug = isDebug;

			appName = String.valueOf(ai.loadLabel(pm));
			Utils.sLogTag = appName;
			packageName = mContext.getPackageName();

			telMgr = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
//			imei = telMgr.getDeviceId();
//			sim = telMgr.getSimSerialNumber();
		} catch (NameNotFoundException e) {
			Log.e(TAG, "met some error when get application info");
		}
	}

	// public String getCid() {
	// if (TextUtils.isEmpty(cid)) {
	// getApplicationInfo();
	// }
	// return cid;
	// }
	//
	// public String getCpid() {
	// if (TextUtils.isEmpty(cpid)) {
	// getApplicationInfo();
	// }
	// return cpid;
	// }

	public String getVersionName() {
		if (TextUtils.isEmpty(versionName)) {
			getApplicationInfo();
		}
		return versionName;
	}

	public int getVersionCode() {
		if (versionCode <= 0) {
			getApplicationInfo();
		}
		return versionCode;
	}

//	 public String getIMEI() {
//	 if (TextUtils.isEmpty(imei)) {
//		 getApplicationInfo();
//	 }
//	 return imei;
//	 }

	public String getPackageName() {
		if (TextUtils.isEmpty(packageName)) {
			getApplicationInfo();
		}
		return packageName;
	}

//	 public String getSim() {
//		 if (TextUtils.isEmpty(sim)) {
//			 getApplicationInfo();
//		 }
//		 return sim;
//	 }

	public String getMac() {
		if (TextUtils.isEmpty(macAddress)) {
			WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
			WifiInfo info = wifi.getConnectionInfo();
			macAddress = info.getMacAddress();
		}
		return macAddress;
	}

	
	
	
	
	public String getUserIcon() {
		return userIcon;
	}

	public void setUserIcon(String userIcon) {
		this.userIcon = userIcon;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_USERICON, userIcon));
	}


	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {

		this.userName = userName;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_USERNAME, userName));
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_ACCOUNT, account));
	}

	public String getUserSex() {
		return userSex;
	}

	public void setUserSex(String userSex) {
		this.userSex = userSex;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_SEX, userSex));
	}

	public String getUserBriday() {
		return userBriday;
	}

	public void setUserBriday(String userBriday) {
		this.userBriday = userBriday;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_BRIDAY, userBriday));
	}

	public String getUserSkinType() {
		return userSkinType;
	}

	public void setUserSkinType(String userSkinType) {
		this.userSkinType = userSkinType;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_SKIN_TYPE, userSkinType));
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_PASSWORD, password));
	}

	public String getAppName() {
		return appName;
	}

	public boolean isUpdateAvailable() {
		return isUpdateAvailable;
	}

	public void setUpdateAvailable(boolean flag) {
		this.isUpdateAvailable = flag;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_AVAILABIE, flag));
	}

	public String getUpdateVersionName() {
		return updateVersionName;
	}

	public int getUpdateVersionCode() {
		return updateVersionCode;
	}

	public String getUpdateVersionDesc() {
		return updateVersionDesc;
	}

	public String getUpdateUri() {
		return updateUri;
	}

	public int getUpdateLevel() {
		return updateLevel;
	}

	public void setUpdateInfo(String versionName, int versionCode,String description, String url, int level) {

		this.isUpdateAvailable = true;
		this.updateVersionName = versionName;
		this.updateVersionCode = versionCode;
		this.updateVersionDesc = description;
		this.updateUri = url;
		this.updateLevel = level;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_AVAILABIE, true));
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_VERSION_CODE, versionCode));
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_DESC, description));
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_URI, url));
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_VERSION_NAME, versionName));
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_LEVEL, level));
	}

	public long getUpdateId() {
		return updateId;
	}

	public void setUpdateID(long updateId) {
		if (this.updateId == updateId) {
			return;
		}
		this.updateId = updateId;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPDATE_ID, updateId));
	}

	public boolean isAutoClearCache() {
		return isAutoClearCache;
	}

	public String getModel() {
		return model;
	}

	public String getBuildVersion() {
		return buildVersion;
	}

	public boolean isDeviceBinded() {
		return isDeviceBinded;
	}

	public String getDeviceId() {
		return deviceId;
	}

	public int getUpgradeNumber() {
		return upgradeNumber;
	}

	public void setUpgradeNumber(int upgradeNumber) {

		// there is no need to update for [same] value
		if (this.upgradeNumber == upgradeNumber) {
			return;
		}
		this.upgradeNumber = upgradeNumber;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_UPGRADE_NUM, upgradeNumber));
	}

	public long getUpdataCheckTime() {
		return updataCheckTime;
	}

	public void setUpdataCheckTime(long updataCheckTime) {

		// there is no need to update for [same] value
		if (this.updataCheckTime == updataCheckTime) {
			return;
		}
		this.updataCheckTime = updataCheckTime;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_PRODUCT_UPDATE_CHECK_TIMESTAMP,updataCheckTime));
	}

	public String getDebugType() {
		return debugType;
	}

	public void close() {
		mSessionManager.writePreferenceQuickly();
		mInstance = null;
	}

	public long getSplashTime() {
		return splashTime;
	}

	public void setSplashTime(long splashTime) {
		this.splashTime = splashTime;

		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_SPLASH_TIME, splashTime));
	}

	public int getLastVersion() {
		return lastVersion;
	}

	public void setLastVersion(int currentVersion) {

		if (currentVersion == this.lastVersion) {
			return;
		}
		clearData();
		this.lastVersion = currentVersion;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_CURRENT_VERSION, currentVersion));
	}

	/**
	 * 清除上一个版本数据
	 */
	public void clearData() {
		SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
		sp.edit().clear().commit();
	}

	public long getSplashId() {
		return splashId;
	}

	public void setSplashId(long splashId) {
		this.splashId = splashId;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_SPLASH_ID, splashId));
	}

	public String getUserAddress() {
		return userAddress;
	}

	public void setUserAddress(String userAddress) {
		this.userAddress = userAddress;
		super.setChanged();
		super.notifyObservers(new Pair<String, Object>(SessionManager.P_USER_ADDRESS, userAddress));
	}
	
	

}